package com.wwdeng.print.app.meituan;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * PrintTestDemo
 *
 * @Author：wwdeng
 * @CreateTime：2025/6/10 23:39
 * <pre>
 *  打印菜单指令工具
 * </pre>
 */
public class MeiTuanEscPosMenuUtils {

    /**
     * 打印一行四列数据（商品名称、数量、单价、合计）
     * @param productName 商品名称
     * @param quantity 数量
     * @param unitPrice 单价
     * @param total 合计
     * @return 打印机可识别的byte数组指令
     */
    public static byte[] printFourColumns(String productName, String quantity, String unitPrice, String total) {
        // 列宽定义（字符数）
        final int nameColWidth = 30;  // 商品名称列宽
        final int qtyColWidth = 8;    // 数量列宽
        final int priceColWidth = 10;  // 单价列宽
        final int totalColWidth = 10;  // 合计列宽

        // 计算总宽度（用于对齐）
        final int totalWidth = nameColWidth + qtyColWidth + priceColWidth + totalColWidth;

        // 处理商品名称换行
        List<String> nameLines = splitTextToFit(productName, nameColWidth);

        // 构建所有行
        List<String> allLines = new ArrayList<>();

        // 添加标题行
//        allLines.add(buildLine(
//                "商品名称", "数量",
//                "单价", "合计",
//                nameColWidth, qtyColWidth,
//                priceColWidth, totalColWidth));

        // 添加数据行
        if (nameLines.size() == 1) {
            // 名称不需要换行
            allLines.add(buildLine(productName, quantity, unitPrice, total,
                    nameColWidth, qtyColWidth, priceColWidth, totalColWidth));
        } else {
            // 名称需要换行，第一行
            String firstLineName = nameLines.get(0);
            String remainingName = String.join("", nameLines.subList(1, nameLines.size()));

            // 第一行
            allLines.add(buildLine(firstLineName, quantity, "", "",
                    nameColWidth, qtyColWidth, priceColWidth, totalColWidth));

            // 后续行（数量、单价、合计列留空）
            for (int i = 1; i < nameLines.size(); i++) {
                String lineName = nameLines.get(i);
                allLines.add(buildLine(lineName, "", "", "",
                        nameColWidth, qtyColWidth, priceColWidth, totalColWidth));
            }

            // 最后一行补充数量、单价、合计
            String lastLineName = nameLines.get(nameLines.size() - 1);
            allLines.add(buildLine(lastLineName, quantity,unitPrice, total,
                    nameColWidth, qtyColWidth, priceColWidth, totalColWidth));
        }

        // 将所有行转换为ESC/POS指令
        return convertLinesToEscPos(allLines);
    }

    /**
     * 构建单行数据
     */
    private static String buildLine(String name, String qty, String price, String total,
                                    int nameWidth, int qtyWidth, int priceWidth, int totalWidth) {
        StringBuilder sb = new StringBuilder();

        // 商品名称列（居左对齐）
        sb.append(padRight(name, nameWidth));

        // 数量列（居右对齐）
        sb.append(padLeft(qty, qtyWidth));

        // 单价列（居右对齐）
        sb.append(padLeft(price, priceWidth));

        // 合计列（居右对齐）
        sb.append(padLeft(total, totalWidth));

        return sb.toString();
    }

    /**
     * 将文本分割以适应指定宽度
     */
    private static List<String> splitTextToFit(String text, int maxWidth) {
        List<String> lines = new ArrayList<>();
        if (text.length() <= maxWidth) {
            lines.add(text);
            return lines;
        }

        // 简单实现：按空格分割，然后尽可能多地组合单词
        String[] words = text.split(" ");
        StringBuilder currentLine = new StringBuilder();

        for (String word : words) {
            if (currentLine.length() + word.length() + 1 <= maxWidth) {
                if (currentLine.length() > 0) {
                    currentLine.append(" ");
                }
                currentLine.append(word);
            } else {
                if (currentLine.length() > 0) {
                    lines.add(currentLine.toString());
                    currentLine = new StringBuilder();
                }
                // 如果单词本身太长，强制分割
                if (word.length() > maxWidth) {
                    for (int i = 0; i < word.length(); i += maxWidth) {
                        int end = Math.min(i + maxWidth, word.length());
                        lines.add(word.substring(i, end));
                    }
                } else {
                    currentLine.append(word);
                }
            }
        }

        if (currentLine.length() > 0) {
            lines.add(currentLine.toString());
        }

        return lines;
    }

    /**
     * 左填充空格（居右对齐）
     */
    private static String padLeft(String s, int length) {
        if (s.length() >= length) {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        while (sb.length() < length - s.length()) {
            sb.append(' ');
        }
        sb.append(s);
        return sb.toString();
    }

    /**
     * 右填充空格（居左对齐）
     */
    private static String padRight(String s, int length) {
        if (s.length() >= length) {
            return s;
        }
        StringBuilder sb = new StringBuilder(s);
        while (sb.length() < length) {
            sb.append(' ');
        }
        return sb.toString();
    }

    /**
     * 将文本行转换为ESC/POS指令
     */
    private static byte[] convertLinesToEscPos(List<String> lines) {
        StringBuilder textBuilder = new StringBuilder();
        for (String line : lines) {
            textBuilder.append(line).append("\n");
        }
        String printString = textBuilder.toString();
        try {
            return printString.getBytes("GBK");
        } catch (Exception e) {
            return printString.getBytes();
        }
    }
}
